﻿/*
SINACOR - BMF&Bovespa
Arquivo: TabelaCorretagem.cs
Criado em: 20-out-2009 11:31:21
Arquiteto Responsável: RAMelo.7Comm
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Sinacor.Infra.Service.Validation;
using Sinacor.Infra.Service.Common;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using Sinacor.Infra.Service.Validation.BusinessRules;

namespace Sinacor.Servico.Bovespa.Corretagem.BusinessLogic
{
    public class TabelaCorretagem : BaseBusinessLogic
    {
        #region Constantes de Erro

        private const int ERRO_OBJETO_NULO = 109514;

        #endregion

        #region Atributos

        ResourceAccess.TabelaCorretagem _raTabelaCorretagem = null;

        #endregion

        #region Construtores

        public TabelaCorretagem() : base() 
        {
            this._raTabelaCorretagem = new ResourceAccess.TabelaCorretagem();
        }

        #endregion

        #region AlterarTabelaCorretagem

        /// <summary>
        /// Efetua alterações em uma tabela de corretagem
        /// </summary>
        /// <param name="entity">Parâmetro para efetuar alterações em uma tabela de corretagem</param>
        public void AlterarTabelaCorretagem(BusinessEntity.TabelaCorretagem entity)
        {
            BusinessLogic.DescontoDiferenciado blDescontoDiferenciado = null;
            BusinessLogic.FaixaAplicacao blFaixaAplicacao = null;
            BusinessRuleValidation.CamposObrigatoriosTabelaCorretagem camposObrigatoriosTabelaCorretagem = null;
            BusinessRulesValidator validador = null;

            if (entity != null)
            {
                blDescontoDiferenciado = new BusinessLogic.DescontoDiferenciado();
                blFaixaAplicacao = new BusinessLogic.FaixaAplicacao();
                camposObrigatoriosTabelaCorretagem = new BusinessRuleValidation.CamposObrigatoriosTabelaCorretagem();
                camposObrigatoriosTabelaCorretagem.EntityToValidate = entity;

                validador = new BusinessRulesValidator();
                validador.AddValidation("CamposObrigatoriosTabelaCorretagem", camposObrigatoriosTabelaCorretagem);

                validador.Validate();
                
                this._raTabelaCorretagem.AlterarTabelaCorretagem(entity);

                blDescontoDiferenciado.ExcluirTodosDescontosDiferenciados(new BusinessEntity.Parameter.FiltroDescontoDiferenciadoChave
                {
                    CodigoTabela = entity.Codigo
                });

                if (entity.IndicadorDescontoDiferenciado.HasValue && entity.IndicadorDescontoDiferenciado.Value)
                {
                    this.RelacionarDescontosComTabela(ref entity);
                    blDescontoDiferenciado.IncluirDescontosDiferenciados(entity.Descontos);
                }

                this.RelacionarFaixasComTabela(ref entity);
                blFaixaAplicacao.AtualizarFaixasAplicacao(entity.Faixas);
                
            }
            else
            {
                throw new BusinessException(ERRO_OBJETO_NULO);
            }
        }

        #endregion

        #region ConsultarTabelasCorretagem

        /// <summary>
        /// Consulta tabelas de corretagem conforme filtro
        /// </summary>
        /// <param name="parameter">Parâmetro para consultar tabelas de corretagem</param>
        public List<BusinessEntity.TabelaCorretagem> ConsultarTabelasCorretagem(BusinessEntity.Parameter.FiltroTabelaCorretagem parameter)
        {
            return this._raTabelaCorretagem.ConsultarTabelasCorretagem(parameter);
        }

        #endregion

        #region DuplicarTabelaCorretagem

        /// <summary>
        /// Duplica uma tabela de corretagem
        /// </summary>
        /// <param name="parameter">Parâmetro para duplicar uma tabela de corretagem</param>
        public BusinessEntity.TabelaCorretagem DuplicarTabelaCorretagem(BusinessEntity.Parameter.FiltroTabelaCorretagemChave parameter)
        {
            BusinessEntity.TabelaCorretagem tabelaCorretagem = null;

            if (parameter != null)
            {
                BusinessRuleValidation.VerificaNaoExistenciaTabelaCorretagem verificaNaoExistenciaTabelaCorretagem = new BusinessRuleValidation.VerificaNaoExistenciaTabelaCorretagem();
                verificaNaoExistenciaTabelaCorretagem.EntityToValidate = new Sinacor.Servico.Bovespa.Corretagem.BusinessEntity.TabelaCorretagem
                {
                    Codigo = parameter.Codigo
                };

                BusinessRulesValidator validador = new BusinessRulesValidator();
                validador.AddValidation("VerificaNaoExistenciaTabelaCorretagem", verificaNaoExistenciaTabelaCorretagem);

                validador.Validate();

                tabelaCorretagem = this._raTabelaCorretagem.DuplicarTabelaCorretagem(parameter);

                new BusinessLogic.DescontoDiferenciado().DuplicarDescontosDiferenciados(parameter, ref tabelaCorretagem);
                new BusinessLogic.FaixaAplicacao().DuplicarFaixaAplicacao(parameter, ref tabelaCorretagem);
            }
            else
            {
                throw new BusinessException(ERRO_OBJETO_NULO);
            }

            return tabelaCorretagem;
        }

        #endregion

        #region ExcluirTabelaCorretagem

        /// <summary>
        /// Excluir uma tabela de corretagem
        /// </summary>
        /// <param name="parameter">Parâmetro para excluir uma tabela de corretagem</param>
        public void ExcluirTabelaCorretagem(BusinessEntity.Parameter.FiltroTabelaCorretagemChave parameter)
        {
            if (parameter != null)
            {
                BusinessRuleValidation.ValidaExclusaoTabelaCorretagem validaExclusaoTabelaCorretagem = new BusinessRuleValidation.ValidaExclusaoTabelaCorretagem();
                validaExclusaoTabelaCorretagem.EntityToValidate = new BusinessEntity.TabelaCorretagem
                {
                     Codigo = parameter.Codigo
                };

                BusinessRulesValidator validador = new BusinessRulesValidator();
                validador.AddValidation("ValidaExclusaoTabelaCorretagem", validaExclusaoTabelaCorretagem);
                validador.Validate();

                new BusinessLogic.FaixaAplicacao().ExcluirTodasFaixasAplicacao(new BusinessEntity.Parameter.FiltroFaixaAplicacaoChave
                {
                    CodigoTabela = parameter.Codigo
                });

                new BusinessLogic.DescontoDiferenciado().ExcluirTodosDescontosDiferenciados(new BusinessEntity.Parameter.FiltroDescontoDiferenciadoChave
                {
                    CodigoTabela = parameter.Codigo
                });

                this._raTabelaCorretagem.ExcluirTabelaCorretagem(parameter);
            }
            else
            {
                throw new BusinessException(ERRO_OBJETO_NULO);
            }
        }

        #endregion

        #region IncluirTabelaCorretagem

        /// <summary>
        /// Inclui uma nova tabela de corretagem
        /// </summary>
        /// <param name="entity">Parâmetro para incluir uma nova tabela de corretagem</param>
        public void IncluirTabelaCorretagem(BusinessEntity.TabelaCorretagem entity)
        {
            BusinessRuleValidation.CamposObrigatoriosTabelaCorretagem camposObrigatoriosTabelaCorretagem = null;
            BusinessRuleValidation.VerificaExistenciaTabelaCorretagem verificaExistenciaTabelaCorretagem = null;
            BusinessRulesValidator validador = null;

            if (entity != null)
            {
                camposObrigatoriosTabelaCorretagem = new BusinessRuleValidation.CamposObrigatoriosTabelaCorretagem();
                verificaExistenciaTabelaCorretagem = new BusinessRuleValidation.VerificaExistenciaTabelaCorretagem();
                camposObrigatoriosTabelaCorretagem.EntityToValidate = entity;
                verificaExistenciaTabelaCorretagem.EntityToValidate = entity;

                validador = new BusinessRulesValidator();
                validador.AddValidation("CamposObrigatoriosTabelaCorretagem", camposObrigatoriosTabelaCorretagem);
                validador.AddValidation("VerificaExistenciaTabelaCorretagem", verificaExistenciaTabelaCorretagem);

                validador.Validate();

                this._raTabelaCorretagem.IncluirTabelaCorretagem(entity);

                if (entity.IndicadorDescontoDiferenciado.HasValue && entity.IndicadorDescontoDiferenciado.Value)
                {
                    this.RelacionarDescontosComTabela(ref entity);
                    new BusinessLogic.DescontoDiferenciado().IncluirDescontosDiferenciados(entity.Descontos);
                }

                this.RelacionarFaixasComTabela(ref entity);
                new BusinessLogic.FaixaAplicacao().IncluirFaixasAplicacao(entity.Faixas);
            }
            else
            {
                throw new BusinessException(ERRO_OBJETO_NULO);
            }
        }

        #endregion

        #region ObterTabelaCorretagem

        /// <summary>
        /// Obtem uma tabela de corretagem
        /// </summary>
        /// <param name="parameter">Parâmetro para obter uma tabela de corretagem</param>
        public BusinessEntity.TabelaCorretagem ObterTabelaCorretagem(BusinessEntity.Parameter.FiltroTabelaCorretagemChave parameter)
        {
            BusinessEntity.TabelaCorretagem tabelaCorretagem = null;
            List<BusinessEntity.DescontoDiferenciado> descontosDiferenciados = null;
            List<BusinessEntity.FaixaAplicacao> faixasAplicacoes = null;

            if (parameter != null)
            {
                tabelaCorretagem = this._raTabelaCorretagem.ObterTabelaCorretagem(parameter);

                descontosDiferenciados = new BusinessLogic.DescontoDiferenciado().ConsultarDescontosDiferenciados(new BusinessEntity.Parameter.FiltroDescontoDiferenciado
                {
                    CodigoTabela = parameter.Codigo
                });

                faixasAplicacoes = new BusinessLogic.FaixaAplicacao().ConsultarFaixasAplicacao(new BusinessEntity.Parameter.FiltroFaixaAplicacao
                {
                    CodigoTabela = parameter.Codigo
                });

                if (tabelaCorretagem != null)
                {
                    tabelaCorretagem.Descontos = descontosDiferenciados;
                    tabelaCorretagem.Faixas = faixasAplicacoes;
                }
            }
            else
            {
                throw new BusinessException(ERRO_OBJETO_NULO);
            }

            return tabelaCorretagem;
        }

        #endregion

        #region RelacionarDescontosComTabela

        /// <summary>
        /// Relaciona o codigo da tabela de corretagem com todas as entidades de descontos
        /// diferenciados contidas na propriedade "Descontos".
        /// </summary>
        /// <param name="entity">Tabela de corretagem</param>
        private void RelacionarDescontosComTabela(ref BusinessEntity.TabelaCorretagem entity)
        {
            if (entity.IndicadorDescontoDiferenciado.HasValue && entity.IndicadorDescontoDiferenciado.Value)
            {
                foreach (BusinessEntity.DescontoDiferenciado item in entity.Descontos)
                {
                    item.CodigoTabela = (entity.Codigo.HasValue ? entity.Codigo.Value : 0);
                }
            }
        }

        #endregion

        #region RelacionarFaixasComTabela

        /// <summary>
        /// Relaciona o codigo da tabela de corretagem com a lista de entidades faixas de
        /// aplicação contidas na propriedade "Faixas"
        /// </summary>
        /// <param name="entity">Tabela de corretagem</param>
        private void RelacionarFaixasComTabela(ref BusinessEntity.TabelaCorretagem entity)
        {
            foreach (BusinessEntity.FaixaAplicacao item in entity.Faixas)
            {
                item.CodigoTabela = entity.Codigo;
            }
        }

        #endregion        
    }
}